package phttp

import (
	"sync"

	"gitee.com/linxing_3/sr-core/config"
	"gitee.com/linxing_3/sr-core/relay"
	"gitee.com/linxing_3/sr-core/server/net/http"
	"gitee.com/linxing_3/sr-core/server/net/http/session"
	"gitee.com/linxing_3/sr-core/yerr"
	"gitee.com/mkwchecking/sr-admin/pkg/instance"
)

type HttpSvrKey struct{}

var httpLock = &sync.Mutex{}

func UpsertHttpSvr() (http.IHttpServer, error) {
	httpLock.Lock()
	defer httpLock.Unlock()

	svr, err := instance.GetOrInit(HttpSvrKey{}, initHttp)
	if err != nil {
		return nil, err
	}

	return *svr, nil
}

func GetHttpE() (http.IHttpServer, error) {
	svr, err := instance.GetInstance[http.IHttpServer](HttpSvrKey{})
	if err != nil {
		return nil, err
	}
	return *svr, nil
}

func MustGetHttp() http.IHttpServer {
	svr, err := GetHttpE()
	if err != nil {
		panic(err)
	}
	return svr
}

func UpsertSession() (*session.SessionManager, error) {
	session, err := instance.GetOrInit(session.YSessionKey{}, initSession)
	if err != nil {
		return nil, err
	}

	return *session, nil
}

func GetSessionE() (*session.SessionManager, error) {
	session, err := instance.GetInstance[*session.SessionManager](session.YSessionKey{})
	if err != nil {
		return nil, err
	}
	return *session, nil
}

func MustGetSession() *session.SessionManager {
	session, err := GetSessionE()
	if err != nil {
		panic(err)
	}
	return session
}

func initHttp() (http.IHttpServer, error) {
	if svr, ok := http.FromCtx(relay.Context()); ok {
		return svr, nil
	}

	srv, err := http.NewServer(config.Get().HttpServer)
	if err != nil {
		return nil, err
	}

	UpsertSession()
	return srv, nil
}

func initSession() (*session.SessionManager, error) {
	if session, ok := session.FromCtx(relay.Context()); ok {
		return session, nil
	}

	if config.Get().HttpServer.Session == nil {
		return nil, yerr.ErrBizParamRequired.Error("session")
	}

	return session.NewSessionManager(relay.Context(), config.Get().HttpServer.Session)
}
